package com.yonyou.brigade.facade.util;

import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @Description: 友空间集成util
 * @Date: 2018/9/25 16:34
 */
@Component
public class YYSpaceUtil {
    private static final Logger logger = LoggerFactory.getLogger(YYSpaceUtil.class);

    @Value("${yyspace.token}")
    private String YYSPACE_TOKEN;

    @Value("${yyspace.version}")
    private String YYSPACE_VERSION;

    @Value("${yyspace.agentId}")
    private String YYSPACE_AGENT_ID;

    @Value("${yyspace.salt}")
    private String YYSPACE_SALT;

    public TreeMap<String, String> genParams(String uri, TreeMap<String, String> params) {
        params = params == null ? new TreeMap<>() : params;
        // token
        params.put("token", YYSPACE_TOKEN);
        // timestamp
        params.put("timestamp", Long.toString(System.currentTimeMillis()));
        // v
        params.put("v", YYSPACE_VERSION);
        // agentId
        params.put("agent_id", YYSPACE_AGENT_ID);
        // sign
        String sign = getSign(uri, params);
        params.put("sign", sign);
        return params;
    }

    /**
     * 根据uri和参数签名
     * sign = md5(URI+STR+SALT)
     * STR:参数数组按键由小到大排序（除去sign字段）
     * 拼装成http query形式：param1=value1&param2=value2&...&paramn=valuen
     *
     * @param uri
     * @param params
     * @return
     */
    private String getSign(String uri, TreeMap<String, String> params) {
        StringBuilder sb = new StringBuilder();
        // uri
        sb.append(uri);
        // params
        Set<Map.Entry<String, String>> paramSet = params.entrySet();
        for (Map.Entry<String, String> param : paramSet) {
            sb.append(param.getKey()).append("=").append(param.getValue()).append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        // salt
        sb.append(YYSPACE_SALT);
        return encryptMD5(sb.toString(), true);
    }

    private String encryptMD5(String originalStr, boolean toLowerCase) {
        try {
            // digest
            MessageDigest digest = MessageDigest.getInstance("MD5");
            // 计算md5函数
            digest.update(originalStr.getBytes(StandardCharsets.UTF_8));
            return new String(Hex.encodeHex(digest.digest(), toLowerCase));
        } catch (NoSuchAlgorithmException e) {
            logger.error("encryptMD5 faild", e);
            return "";
        }
    }
}
